/*
 * Copyright (c) 2019.  drakelee.base All rights reserved.
 */

package com.base.components.task.service;

import com.base.components.common.dto.page.DataPage;
import com.base.components.common.service.task.SysTask;
import com.base.components.common.service.task.SysTaskLog;
import com.base.components.common.util.UUIDUtils;
import com.base.components.database.dao.base.condition.ConditionGroup;
import com.base.components.task.exception.OtherServerHandledException;
import com.google.common.base.Strings;
import com.google.common.base.Throwables;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Pageable;
import org.springframework.transaction.annotation.Transactional;

import java.util.Date;
import java.util.Map;

/**
 * 作业日志
 *
 * @author <a href="drakelee1221@gmail.com">LiGeng</a>
 * @version 1.0.0, 2017-08-03 15:04
 *
 */
public abstract class SysTaskLogService {
  @Autowired
  private SysTaskService sysTaskService;

  public SysTaskLog addTaskLog(String taskId, String resultMessage, Throwable exceptions, Date fireDate) {
    if (!Strings.isNullOrEmpty(taskId)) {
      SysTask task = sysTaskService.findById(taskId);
      if (task != null) {
        return addTaskLog(task, resultMessage, exceptions, fireDate);
      }
    }
    return null;
  }

  @Transactional(rollbackFor = Exception.class)
  public SysTaskLog addTaskLog(SysTask task, String resultMessage, Throwable exception, Date fireDate) {
    if (task == null ) {
      return null;
    }
    SysTaskLog log = newSysTaskLog();
    log.setId(UUIDUtils.generateKey());
    log.setTaskId(task.getId());
    log.setTaskName(task.getName());
    log.setResultMessage(resultMessage.length() > 2000 ? resultMessage.substring(0,2000):resultMessage);
    if(exception != null){
      log.setExecuteSuccess(false);
      Throwable root = Throwables.getRootCause(exception);
      if(root != null){
        exception = root;
      }
      String stack = exception.getMessage();
      if(exception instanceof OtherServerHandledException){
        log.setExecuteSuccess(true);
      }else{
        stack = Throwables.getStackTraceAsString(exception);
      }
      log.setExecuteExceptions(
          stack.length() > 2000 ? stack.substring(0,2000):stack
      );
    }else{
      log.setExecuteSuccess(true);
    }
    log.setExecuteServerHost(TaskManager.serverHost);
    log.setTaskFireTime(fireDate);
    log.setExecuteOverTime(new Date());
    save(log);
    return log;
  }

  public abstract SysTaskLog save(SysTaskLog sysTaskLog);

  public abstract DataPage<SysTaskLog> findAll(ConditionGroup conditionGroup, Pageable pageable);

  public abstract int delete(Map<String, String> params);

  public abstract SysTaskLog newSysTaskLog();
}
